<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="xbsj-labels" content="Earth示例"></meta>
    <title>自定义图元-圆</title>
    <!-- 0 引入js文件 -->
    <script src="../../XbsjEarth/XbsjEarth.js"></script>
    <style>
        html,
        body {
            width: 100%;
            height: 100%;
            margin: 0px;
            padding: 0px;
        }

        #canvas-container {
            width: 600px;
            height: 600px;
            position: absolute;
            right: 0px;
            top: 0px;
        }
    </style>
</head>

<body>
    <div id="earthContainer" style="width: 100%; height: 100%; background: grey">
    </div>
    <script>
        var earth;
        var bgImagery;

        function startup() {
            earth = new XE.Earth('earthContainer');

            earth.sceneTree.root = {
                "children": [
                    {
                        "czmObject": {
                            "name": "默认离线影像",
                            "xbsjType": "Imagery",
                            "xbsjImageryProvider": {
                                "createTileMapServiceImageryProvider": {
                                    "url": XE.HTML.cesiumDir + 'Assets/Textures/NaturalEarthII',
                                    "fileExtension": 'jpg',
                                },
                                "type": "createTileMapServiceImageryProvider"
                            }
                        }
                    },
                ]
            };

            const evalString = `
                if (p._drawArrow) {
                    return;
                }

                // ctx：Canvas绘图环境
                // fromX, fromY：起点坐标（也可以换成p1，只不过它是一个数组）
                // toX, toY：终点坐标 (也可以换成p2，只不过它是一个数组)
                // theta：三角斜边一直线夹角
                // headlen：三角斜边长度
                // width：箭头线宽度
                // color：箭头颜色
                function drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {

                    theta = typeof (theta) != 'undefined' ? theta : 30;
                    headlen = typeof (theta) != 'undefined' ? headlen : 10;
                    width = typeof (width) != 'undefined' ? width : 1;
                    color = typeof (color) != 'color' ? color : '#000';

                    // 计算各角度和对应的P2,P3坐标
                    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
                        angle1 = (angle + theta) * Math.PI / 180,
                        angle2 = (angle - theta) * Math.PI / 180,
                        topX = headlen * Math.cos(angle1),
                        topY = headlen * Math.sin(angle1),
                        botX = headlen * Math.cos(angle2),
                        botY = headlen * Math.sin(angle2);

                    ctx.save();
                    ctx.beginPath();

                    var arrowX = fromX - topX,
                        arrowY = fromY - topY;

                    ctx.moveTo(arrowX, arrowY);
                    ctx.moveTo(fromX, fromY);
                    ctx.lineTo(toX, toY);
                    arrowX = toX + topX;
                    arrowY = toY + topY;
                    ctx.moveTo(arrowX, arrowY);
                    ctx.lineTo(toX, toY);
                    arrowX = toX + botX;
                    arrowY = toY + botY;
                    ctx.lineTo(arrowX, arrowY);
                    ctx.strokeStyle = color;
                    ctx.lineWidth = width;
                    ctx.stroke();
                    ctx.restore();
                }

                p._drawArrow = drawArrow;
                p._angle = 0;
            `;

            const preUpdateEvalString = `
                p._angle += 1;
                if (p._angle > 360.0) {
                    p._angle = 0.0;
                }
                const angle = p._angle;

                p.drawCanvas(ctx => {
                    ctx.clearRect(0, 0, 256, 256);

                    ctx.save();

                    ctx.translate(128, 128);
                    ctx.rotate(-angle * Math.PI / 180.0);

                    // 状态设置
                    ctx.strokeStyle = "rgb(255, 255, 0)"; 
                    ctx.setLineDash([8, 8]);
                    ctx.lineWidth = 3;
                    
                    // 大圆
                    ctx.beginPath();
                    ctx.arc(0, 0, 120, 0, Math.PI*2, true);
                    ctx.stroke();

                    // 小圆
                    // ctx.beginPath();
                    // ctx.arc(0, 0, 64, 0, Math.PI*2, true);
                    // ctx.stroke();

                    p._drawArrow(ctx, 0, 0, 120, 0, 30, 10, 3, "rgb(255, 255, 0)");

                    ctx.font = "12px Microsoft YaHei";
                    ctx.fillStyle = "rgb(256, 255, 0)";
                    ctx.fillText("5公里", 40, -5);

                    ctx.restore();
                });
            `;

            const config = {
                position: [116.39, 39.9, 10.0].xeptr,
                positions: XE.Obj.CustomPrimitive.Geometry.unitSquare.positions,
                sts: XE.Obj.CustomPrimitive.Geometry.unitSquare.sts,
                indices: XE.Obj.CustomPrimitive.Geometry.unitSquare.indices,
                scale: [100, 100, 1],
                renderState: XE.Obj.CustomPrimitive.getRenderState(true, true),
                canvasWidth: 256,
                canvasHeight: 256,
                preUpdateEvalString,
                evalString,
            };

            var p = new XE.Obj.CustomPrimitive(earth)
            p.xbsjFromJSON(config);
            p.flyTo();

            window.p = p; // 方便调试
        }

        // 1 XE.ready()会加载Cesium.js等其他资源，注意ready()返回一个Promise对象。
        XE.ready().then(startup);     

        
        // ctx：Canvas绘图环境
        // fromX, fromY：起点坐标（也可以换成p1，只不过它是一个数组）
        // toX, toY：终点坐标 (也可以换成p2，只不过它是一个数组)
        // theta：三角斜边一直线夹角
        // headlen：三角斜边长度
        // width：箭头线宽度
        // color：箭头颜色
        function drawArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {

            theta = typeof (theta) != 'undefined' ? theta : 30;
            headlen = typeof (theta) != 'undefined' ? headlen : 10;
            width = typeof (width) != 'undefined' ? width : 1;
            color = typeof (color) != 'color' ? color : '#000';

            // 计算各角度和对应的P2,P3坐标
            var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
                angle1 = (angle + theta) * Math.PI / 180,
                angle2 = (angle - theta) * Math.PI / 180,
                topX = headlen * Math.cos(angle1),
                topY = headlen * Math.sin(angle1),
                botX = headlen * Math.cos(angle2),
                botY = headlen * Math.sin(angle2);

            ctx.save();
            ctx.beginPath();

            var arrowX = fromX - topX,
                arrowY = fromY - topY;

            ctx.moveTo(arrowX, arrowY);
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            arrowX = toX + topX;
            arrowY = toY + topY;
            ctx.moveTo(arrowX, arrowY);
            ctx.lineTo(toX, toY);
            arrowX = toX + botX;
            arrowY = toY + botY;
            ctx.lineTo(arrowX, arrowY);
            ctx.strokeStyle = color;
            ctx.lineWidth = width;
            ctx.stroke();
            ctx.restore();
        }
        
        function drawDoubleArrow(ctx, fromX, fromY, toX, toY, theta, headlen, width, color) {
            theta = typeof(theta) != 'undefined' ? theta : 30;
            headlen = typeof(theta) != 'undefined' ? headlen : 10;
            width = typeof(width) != 'undefined' ? width : 1;
            color = typeof(color) != 'color' ? color : '#000';
        
            var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
                angle1 = (angle + theta) * Math.PI / 180,
                angle2 = (angle - theta) * Math.PI / 180,
                topX = headlen * Math.cos(angle1),
                topY = headlen * Math.sin(angle1),
                botX = headlen * Math.cos(angle2),
                botY = headlen * Math.sin(angle2);
        
        
            ctx.save();
            ctx.beginPath();
        
            var arrowX = fromX - topX,
                arrowY = fromY - topY;
            ctx.moveTo(arrowX, arrowY);
            ctx.lineTo(fromX, fromY);
            arrowX = fromX - botX;
            arrowY = fromY - botY;
            ctx.lineTo(arrowX, arrowY);
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
        
            // Reverse length on the other side
            arrowX = toX + topX;
            arrowY = toY + topY;
            ctx.moveTo(arrowX, arrowY);
            ctx.lineTo(toX, toY);
            arrowX = toX + botX;
            arrowY = toY + botY;
            ctx.lineTo(arrowX, arrowY);
            ctx.strokeStyle = color;
            ctx.lineWidth = width;
            ctx.stroke();
            ctx.restore();
        }

    </script>
</body>

</html>